import type { SerialPort } from '../models/up_serial_port.ts';
import type { BaseResponse } from '../models/up_response.ts';
import type {
  AngleRpmRequest,
  OpenSerialRequest,
} from '../models/up_request.ts';
import { SerialPortFactory } from '../models/factories/SerialPortFactory';
import apiClient from '../utils/axiosInterceptors';

export class SerialService {
  /** 通用 GET 并校验返回数据 */
  private static async getAndCheck<T>(url: string): Promise<T> {
    const response = await apiClient.get<BaseResponse<T>>(url);
    if (response.data.status && response.data.data) {
      return response.data.data;
    }
    throw SerialPortFactory.createSerialError(
      response.data.message || 'Unknown error'
    );
  }

  /** 通用 POST 并校验返回数据 */
  private static async postAndCheck<T>(url: string, data?: any): Promise<T> {
    const response = await apiClient.post<BaseResponse<T>>(url, data);
    if (response.data.status && response.data.data) {
      return response.data.data;
    }
    throw SerialPortFactory.createSerialError(
      response.data.message || 'Unknown error'
    );
  }

  /** 通用 POST 只校验 status */
  private static async postStatus(url: string, data?: any): Promise<boolean> {
    const response = await apiClient.post<BaseResponse<null>>(url, data);
    if (response.data.status) {
      return true;
    }
    throw SerialPortFactory.createSerialError(
      response.data.message || 'Unknown error'
    );
  }

  // 获取可用串口列表
  static fetchPorts(): Promise<SerialPort[]> {
    return this.getAndCheck<SerialPort[]>('/serial/list_serial_ports');
  }

  // 打开串口
  static openSerial(formData: OpenSerialRequest): Promise<string> {
    return this.postAndCheck<string>('/serial/open', formData);
  }

  // 复位
  static reset(serial_id: string, protocol_id: number): Promise<boolean> {
    return this.postStatus(
      '/serial/reset',
      SerialPortFactory.createHttpRequest(serial_id, protocol_id)
    );
  }

  // 关闭串口
  static closeSerial(serial_id: string): Promise<boolean> {
    return this.postStatus(
      '/serial/close',
      SerialPortFactory.createSerialRequest(serial_id)
    );
  }

  // 异步写
  static asyncWrite(serial_id: string, raw_data: string): Promise<string> {
    return this.postAndCheck<string>(
      '/serial/async_write',
      SerialPortFactory.createWriteRequest(serial_id, raw_data)
    );
  }

  // 通用请求
  static request(
    suffix: string,
    serial_id: string,
    protocol_id: number
  ): Promise<boolean> {
    return this.postStatus(
      suffix,
      SerialPortFactory.createHttpRequest(serial_id, protocol_id)
    );
  }
}
